import org.apache.commons.math3.analysis.interpolation.SplineInterpolator;
import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction;

public class BicubicSpline {

    public static void main(String[] args) {
        // 生成二维数组
        double[][] data = generate2DArray();
        
        // 创建插值器
        SplineInterpolator interpolator = new SplineInterpolator();
        
        // 第一维插值点
        double[] x1 = new double[38];
        for (int i = 0; i < 38; i++) {
            x1[i] = -1047 + i * (264 + 1047) / 37.0;
        }
        
        // 第二维插值点
        double[] x2 = new double[7];
        for (int i = 0; i < 7; i++) {
            x2[i] = 125 + i * (264 - 125) / 6.0;
        }
        
        // 创建插值网格
        double[] x1New = new double[(int)((264 + 1047) / 5) + 1];
        for (int i = 0; i < x1New.length; i++) {
            x1New[i] = -1047 + i * 5;
        }
        
        double[] x2New = new double[(int)((264 - 125) / 5) + 1];
        for (int i = 0; i < x2New.length; i++) {
            x2New[i] = 125 + i * 5;
        }
        
        // 执行双三次样条插值
        double[][] interpolated = new double[x1New.length][x2New.length];
        
        // 对每个x2值进行一维插值
        for (int j = 0; j < x2New.length; j++) {
            // 创建当前x2对应的y值数组
            double[] yForFixedX2 = new double[38];
            for (int i = 0; i < 38; i++) {
                // 对当前x2值进行插值获取y值
                PolynomialSplineFunction spline = interpolator.interpolate(x2, getSlice(data, i));
                yForFixedX2[i] = spline.value(x2New[j]);
            }
            
            // 对x1维度进行插值
            PolynomialSplineFunction finalSpline = interpolator.interpolate(x1, yForFixedX2);
            for (int i = 0; i < x1New.length; i++) {
                interpolated[i][j] = finalSpline.value(x1New[i]);
            }
        }
        
        System.out.println("原始数组大小: 38 x 7");
        System.out.println("插值后大小: " + interpolated.length + " x " + interpolated[0].length);
        System.out.printf("插值点示例: x1=%.1f, x2=%.1f, y=%.4f%n", 
                         x1New[10], x2New[5], interpolated[10][5]);
    }
    
    // 获取二维数组的指定行
    private static double[] getSlice(double[][] data, int index) {
        double[] slice = new double[7];
        for (int j = 0; j < 7; j++) {
            slice[j] = data[index][j];
        }
        return slice;
    }
    
    // 生成二维数组和函数值
    private static double[][] generate2DArray() {
        double[][] data = new double[38][7];
        
        // 填充数组 (示例函数)
        for (int i = 0; i < 38; i++) {
            double x1 = -1047 + i * (264 + 1047) / 37.0;
            for (int j = 0; j < 7; j++) {
                double x2 = 125 + j * (264 - 125) / 6.0;
                data[i][j] = Math.sin(x1/100) * Math.cos(x2/100);
            }
        }
        
        return data;
    }
}